<script>
import {mapGetters, mapState} from "vuex";

export default {
  name: "deptDialog",
  props: {
    /* 父组件传递过来的showDialog属性用于控制该组件的显示和隐藏 */
    showDialog: {
      type: Boolean,
      default: false
    },
    /* 父组件传递过来的pid(父级部门的ID，子组件在添加部门时需要使用此参数) */
    pid: {
      type: String,
      required: true
    }
  },
  data() {
    /* 自定义校验部门编码的回调函数:部门的编码在整个模块中不能重复 */
    const validateCode = (rule, value, callback) => {
      /*// 定义一个dept变量
       let dept = null
       // 如果有ID证明是编辑状态
       if (this.formData.id) {
         // 编辑状态要使用filter()过滤出当前正在编辑的部门形成一个新的部门数组然后find()查找
         dept = this.simpleDepartments.filter(item => item.id !== this.formData.id).find(item => item.code === value)
       } else {
         // 如果没有ID证明是添加状态，添加状态使用find()查找所有的部门
         dept = this.simpleDepartments.find(item => item.code === value)
       }
       if (dept) {
         // 找到了重复的部门(find()在数组中如果找到了满足添加的元素返回的就是此元素，没有找到返回的是undefined)
         callback(new Error(`输入的部门编码${value}在${dept.name}已经存在`))
       } else {
         // 没有找到重复的部门
         callback()
       }*/
      let dept = this.formData.id ? this.simpleDepartments.filter(item => item.id !== this.formData.id).find(item => item.code === value) : this.simpleDepartments.find(item => item.code === value)
      dept ? callback(new Error(`输入的部门编码${value}在${dept.name}已经存在`)) : callback()
    }
    /* 自定义校验部门名称的回调函数:部门的名称在同级的部门中不能重复 */
    const validateName = (rule, value, callback) => {
      // 当前部门的变量
      let dept = null
      // 当前部门的父部门变量
      let parentDept = null
      if (this.formData.id) {
        dept = this.simpleDepartments.filter(item => item.pid === this.formData.pid && item.id !== this.formData.id).find(item => item.name === value)
        parentDept = this.simpleDepartments.find(item => item.id === dept?.pid)
      } else {
        dept = this.simpleDepartments.filter(item => this.pid === item.pid).find(item => item.name === value)
        parentDept = this.simpleDepartments.find(item => item.id === dept?.pid)
      }
      /*if (dept) {
        callback(new Error(`输入的部门名称${value}在${parentDept?.name || '公司'}已经存在`))
      } else {
        callback()
      }*/
      dept ? callback(new Error(`输入的部门名称${value}在${parentDept?.name || '公司'}已经存在`)) : callback()
    }
    return {
      /* 表单的数据对象(新增部门或者编辑部门需要带给服务器的参数) */
      formData: {
        code: '',  // 部门编码
        introduce: '', // 部门介绍
        manager: '', // 部门负责人名字
        name: '', // 部门名称
        createTime: '', // 部门创建时间
      },
      /* 表单的规则对象(用于对表单进行校验) */
      formRules: {
        code: [
          {required: true, message: '请输入部门编码', trigger: 'blur'},
          {min: 2, max: 10, message: '部门编码为2-10个字符', trigger: 'blur'},
          {trigger: 'blur', validator: validateCode},
        ],
        introduce: [
          {required: true, message: '请输入部门介绍', trigger: 'blur'},
          {min: 2, max: 300, message: '部门介绍为2-300个字符', trigger: 'blur'},
        ],
        manager: [
          {required: true, message: '请选择部门负责人', trigger: 'change'},
        ],
        name: [
          {required: true, message: '请输入部门名称', trigger: 'blur'},
          {min: 2, max: 10, message: '部门名称为2-10个字符', trigger: 'blur'},
          {trigger: 'blur', validator: validateName},
        ],
        createTime: [
          {required: true, message: '请选中部门创建时间', trigger: 'blur'},
        ]
      }
    }
  },
  methods: {
    /* fetchSimpleEmployees函数的作用(派发一个action获取部门负责人) */
    async fetchSimpleEmployees() {
      try {
        await this.$store.dispatch('departmentsStore/fetchSimpleEmployees')
      } catch (error) {
        this.$message.error(error.message)
      }
    },
    /* findDepartmentDetail函数的作用(派发一个action根据部门的ID发送请求获取当前部门详情)
    async findDepartmentDetail(id) {
      try {
        // 调用action发送请求查找当前的部门详情
        const department = await this.$store.dispatch('departmentsStore/findDepartmentDetail', id)
        // 数据回显(服务器返回的当前部门详情)
        this.formData = department
      } catch (error) {
        this.$message.error(error.message)
      }
    },*/
    findDepartmentDetail(department) {
      // 进行深拷贝将数据回显(没有发送请求去查找当前部门详情)
      this.formData = JSON.parse(JSON.stringify(department))
    },

    /* doEditDepartment函数的作用(派发一个action用于修改一个部门) */
    async doEditDepartment() {
      try {
        // 派发一个updateDepartmentDetail的action并且传递发送请求获取部门详情返回的数据在formData中，该action返回的是一个Promise对象
        const message = await this.$store.dispatch('departmentsStore/updateDepartmentDetail', this.formData)
        // 派发一个fetchDepartments的action发送请求重新获取新的部门列表
        await this.$store.dispatch('departmentsStore/fetchDepartments')
        // 关闭弹框
        this.$emit('update:showDialog', false)
        // 提示用户修改部门成功
        this.$message.success(message)
      } catch (error) {
        // 修改部门失败
        this.$message.error(error.message)
      }
    },

    /* doAddDepartment函数的作用(派发一个action用于添加一个部门) */
    async doAddDepartment() {
      try {
        // 整理需要带给服务器的参数(department表单收集的数据)
        const department = {...this.formData, pid: this.pid}
        // 派发一个addDepartments的action并且传递当前组件收集的数据用于发送添加部门的请求，该action返回的是一个Promise对象
        const message = await this.$store.dispatch('departmentsStore/addDepartments', department)
        // 派发一个fetchDepartments的action发送请求重新获取新的部门列表
        await this.$store.dispatch('departmentsStore/fetchDepartments')
        // 关闭弹框
        this.$emit('update:showDialog', false)
        // 提示用户添加部门成功
        this.$message.success(message)
      } catch (error) {
        // 添加部门失败
        this.$message.error(error.message)
      }
    },
    /* 点击确定按钮的回调函数(添加或修改部门) */
    async handleSubmit() {
      // 调用el-form的validate()对整个表单进行校验，参数为回调函数。该函数会在校验结束后被调用，并传入两个参数：是否校验成功和未通过校验的字段。若不传入回调函数则会返回一个promise!!
      const valid = await this.$refs.elForm.validate().catch(error => error)
      // 表单校验失败则return出去不执行下面的逻辑
      if (!valid) return
      //  有ID证明是编辑状态
      if (this.formData.id) {
        // 调用doEditDepartment()去派发action更新部门
        this.doEditDepartment()
      } else {
        //  没有有ID证明是添加状态
        // 调用doAddDepartment()去派发action添加部门
        this.doAddDepartment()
      }
    },
    /* 点击取消按钮的回调函数 */
    handleCancel() {
      this.$emit('update:showDialog', false)
    },
    /* 点击部分负责人下拉框的回调函数 */
    handleClickSelect() {
      //   判断Vuex中是否有部门负责人的数据如果有了就不需要发送请求
      if (this.simpleEmployees.length) return
      // 调用fetchSimpleEmployees()派发一个action去发送请求获取部门负责人数据
      this.fetchSimpleEmployees()
    },
    /* el-dialog关闭时的回调函数 */
    handleClose() {
      // 通知父组件关闭弹框
      this.$emit('update:showDialog', false)
      setTimeout(() => {
        // 重置formData数据为添加部门的状态
        this.formData = {code: '', introduce: '', manager: '', name: '', createTime: ''}
        // 对整个表单进行重置，将所有字段值重置为初始值并移除校验结果
        this.$refs.elForm.resetFields()
      }, 500)
    }
  },
  computed: {
    /* 使用mapState将departmentsStore模块下state中的simpleEmployees映射为组件实例的属性 */
    ...mapState('departmentsStore', ['simpleEmployees']),
    /* 使用mapGetters将departmentsStore模块下getters中的simpleDepartments映射为组件实例的属性 */
    ...mapGetters('departmentsStore', ['simpleDepartments']),
    /* 弹框的标题 */
    title() {
      // 根据formData是否有ID来计算
      return this.formData.id ? '编辑部门' : '添加部门'
    }
  },
  mounted() {
    /* 组件挂载完毕调用fetchSimpleEmployees()派发一个action去发送请求获取部门负责人 */
    // this.fetchSimpleEmployees()
  },

  watch: {
    /*监听showDialog字段的变化如果为false则证明关闭了弹框(重置表单数据以防数据和校验规则残留)
    showDialog(newValue, oldValue) {
      if (newValue) return
        this.$nextTick(() => {
          this.$refs.elForm.resetFields()
        })
    } */
  }
}
</script>

<template>
  <el-dialog v-bind="$attrs" :title="title" :visible="showDialog" @close="handleClose">
    <el-form label-width="100px" :model="formData" :rules="formRules" ref="elForm">
      <el-form-item label="部门名称" prop="name">
        <el-input placeholder="请输入部门名称" v-model="formData.name"></el-input>
      </el-form-item>
      <el-form-item label="部门编码" prop="code">
        <el-input placeholder="请输入部门编码" v-model="formData.code"></el-input>
      </el-form-item>
      <el-form-item label="创建时间" prop="createTime">
        <el-date-picker v-model="formData.createTime" type="datetime" placeholder="请选择部门创建时间"></el-date-picker>
      </el-form-item>
      <el-form-item label="部门负责人" prop="manager">
        <el-select placeholder="请选择部门负责人" v-model="formData.manager" @click.native="handleClickSelect">
          <el-option v-for="(item,index) in simpleEmployees" :value="item.username" :label="item.username" :key="item.id"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="部门介绍" prop="introduce">
        <el-input type="textarea" resize="none" rows="4" placeholder="请输入部门介绍" v-model="formData.introduce"></el-input>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button type="danger" @click="handleCancel">取消</el-button>
      <el-button type="primary" @click="handleSubmit">确定</el-button>
    </template>
  </el-dialog>
</template>

<style scoped lang="scss">
.el-select {
  width: 250px;
}

.el-date-editor {
  width: 250px;
}
</style>
